package ac.biu.nlp.nlp.curator.client;

import java.util.Stack;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

import edu.illinois.cs.cogcomp.thrift.base.AnnotationFailedException;
import edu.illinois.cs.cogcomp.thrift.base.Node;
import edu.illinois.cs.cogcomp.thrift.base.ServiceUnavailableException;
import edu.illinois.cs.cogcomp.thrift.base.Tree;
import edu.illinois.cs.cogcomp.thrift.curator.Curator;
import edu.illinois.cs.cogcomp.thrift.curator.Record;

/**
 * 
 * @author Asher Stern
 * @since Mar 21, 2013
 *
 */
public class Client1
{
	public Client1(String host, int port)
	{
		super();
		this.host = host;
		this.port = port;
		
		constructTransport();
	}
	
	public String process(String text, String annotator) throws ServiceUnavailableException, AnnotationFailedException, TException
	{
		return displayParseView(processText(text,annotator),annotator);
	}

	private void constructTransport()
	{
		transport = new TSocket(host, port);
		transport = new TFramedTransport(transport);
		TProtocol protocol = new TBinaryProtocol(transport);
		client = new Curator.Client(protocol);
	}
	
	private Record processText(String text, String annotatorName) throws ServiceUnavailableException, AnnotationFailedException, TException
	{
		Record record = null;
		transport.open();
		try
		{
			record = client.provide(annotatorName, text, true);
		}
		finally
		{
			transport.close();
		}
		return record;
	}
	
	private String displayParseView(Record record, String recordKey)
	{
		String rawText = record.getRawText();
		StringBuffer result = new StringBuffer();
		result.append("Raw text = \"").append(rawText).append("\n");
		for (Tree depTree : record.getParseViews().get(recordKey).getTrees())
		{
			result.append("\n");
			int top = depTree.getTop(); //this tells us where in nodes the head node is
			Stack<Integer> stack = new Stack<Integer>();
			stack.push(top);
			while (!stack.isEmpty())
			{
				int headIndex = stack.pop();
				Node head = depTree.getNodes().get(headIndex);
				if (!head.isSetChildren())
				{
					continue;
				}
				for (Integer childIndex : head.getChildren().keySet())
				{
					stack.push(childIndex);
					Node child = depTree.getNodes().get(childIndex);
					String relation = head.getChildren().get(childIndex);
					result.append(relation);
					result.append("(");
					result.append(record.getRawText().substring(head.getSpan().getStart(), head.getSpan().getEnding()));
					result.append(", ");
					result.append(record.getRawText().substring(child.getSpan().getStart(), child.getSpan().getEnding()));
					result.append(")\n");
				}
			}
		}
		return result.toString();
	}
	
	private final String host;
	private final int port;
	
	private TTransport transport;
	private Curator.Client client;
	
}
